---
title: "Camera Glasses"
description: "Build apps for camera-equipped glasses - Mentra Live"
---

Camera glasses have cameras for photo/video but no displays.
Example: Mentra Live. These devices are ideal for visual capture, streaming, and audio-based interactions.

## Mentra Live

- **Camera**: 1080p with streaming
- **Display**: No
- **Microphone**: Yes (with VAD)
- **Speaker**: Yes
- **Buttons**: Yes (press, double press, long press)
- **LEDs**: RGB + white privacy light
- **WiFi**: Yes

```typescript
// Mentra Live capabilities
{
  modelName: "Mentra Live",
  hasCamera: true,
  hasDisplay: false,
  hasMicrophone: true,
  hasSpeaker: true,
  hasButton: true,
  hasLight: true,
  hasWifi: true
}
```

## Building for Camera Glasses

### Check Camera Capabilities

```typescript
protected async onSession(session: AppSession, sessionId: string, userId: string) {
  const caps = session.capabilities;

  if (!caps?.hasCamera) {
    session.logger.warn('No camera available');
    return;
  }

  const camera = caps.camera;
  if (camera) {
    session.logger.info('Resolution:', camera.resolution);
    session.logger.info('Can stream:', camera.video.canStream);
    session.logger.info('Can record:', camera.video.canRecord);
  }
}
```

### Photo Capture

```typescript
if (caps.hasCamera) {
  const photo = await session.camera.requestPhoto({
    saveToGallery: true,
    size: 'large'
  });

  session.logger.info('Photo captured:', photo.filename);
  await session.audio.speak('Photo captured');
}
```

### Video Streaming

```typescript
if (caps.camera?.video.canStream) {
  await session.camera.startStream({
    rtmpUrl: 'rtmp://live.example.com/stream/key',
    video: {
      resolution: '1280x720',
      framerate: 30
    }
  });

  await session.audio.speak('Streaming started');
}
```

## Audio-First Interactions

**Without displays, use voice for feedback:**

```typescript
protected async onSession(session: AppSession, sessionId: string, userId: userId: string) {
  // Speak instead of showing text
  await session.audio.speak('Camera ready. Say "photo" to capture.');

  session.events.onTranscription(async (data) => {
    if (!data.isFinal) return;

    if (data.text.toLowerCase().includes('photo')) {
      await this.takePhoto(session);
    }
  });
}

private async takePhoto(session: AppSession) {
  await session.audio.speak('Taking photo');

  const photo = await session.camera.requestPhoto();

  await session.audio.speak('Photo saved');
}
```

## Using Buttons

```typescript
if (caps.hasButton) {
  session.events.onButtonPress(async (data) => {
    if (data.button === 'select') {
      await session.camera.requestPhoto();
      await session.audio.speak('Photo captured');
    }
  });
}
```

## Using LEDs

```typescript
if (caps.hasLight && caps.light) {
  // Check for RGB LED
  const hasRGB = caps.light.lights?.some(led => led.isFullColor);

  if (hasRGB) {
    // Show colored feedback
    await session.led.turnOn({
      color: 'green',
      ontime: 1000
    });
  }
}
```

## WiFi Connectivity

```typescript
if (caps.hasWifi) {
  session.logger.info('Device has WiFi');
  // Can stream without phone tethering
}
```

## Camera Glass Best Practices

**Provide audio feedback:**

```typescript
// ✅ Good - user knows what's happening
await session.audio.speak('Processing');
await processData();
await session.audio.speak('Complete');

// ❌ Avoid - silent operation confuses users
await processData();
```

**Use speaker for output:**

```typescript
if (caps.hasSpeaker) {
  // Audio plays directly on glasses
  await session.audio.speak('Hello!');
} else {
  // Fallback to phone
  await session.audio.speak('Hello!');
}
```

**Combine buttons and voice:**

```typescript
// Button for quick actions
session.events.onButtonPress(async (data) => {
  await session.camera.requestPhoto();
});

// Voice for complex commands
session.events.onTranscription(async (data) => {
  if (data.isFinal) {
    await this.handleCommand(data.text);
  }
});
```

## Example App

```typescript
class CameraGlassesApp extends AppServer {
  protected async onSession(session: AppSession, sessionId: string, userId: string) {
    const caps = session.capabilities;

    if (!caps?.hasCamera) {
      await session.audio.speak('Camera not available');
      return;
    }

    // Audio welcome
    await session.audio.speak('Camera app ready');

    // Button to capture
    session.events.onButtonPress(async (data) => {
      if (data.button === 'select') {
        await this.capturePhoto(session);
      }
    });

    // Voice commands
    session.events.onTranscription(async (data) => {
      if (!data.isFinal) return;

      const text = data.text.toLowerCase();

      if (text.includes('photo')) {
        await this.capturePhoto(session);
      } else if (text.includes('stream')) {
        await this.startStreaming(session);
      }
    });
  }

  private async capturePhoto(session: AppSession) {
    await session.audio.speak('Capturing');

    // LED feedback
    if (session.capabilities?.hasLight) {
      await session.led.blink({
        color: 'white',
        ontime: 100,
        offtime: 100,
        count: 2
      });
    }

    const photo = await session.camera.requestPhoto({
      saveToGallery: true
    });

    await session.audio.speak('Photo saved');
  }

  private async startStreaming(session: AppSession) {
    await session.audio.speak('Starting stream');

    await session.camera.startManagedStream({
      video: {
        resolution: '1280x720',
        framerate: 30
      }
    });

    await session.audio.speak('Streaming');
  }
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Display Glasses" icon="display" href="/app-devs/core-concepts/hardware-capabilities/display-glasses">
    G1, Vuzix - display features
  </Card>
  <Card title="Camera Control" icon="camera" href="/app-devs/core-concepts/app-session/device-control">
    Photo and streaming APIs
  </Card>
  <Card title="Audio" icon="volume" href="/app-devs/core-concepts/speakers/text-to-speech">
    Audio features
  </Card>
  <Card title="Overview" icon="microchip" href="/app-devs/core-concepts/hardware-capabilities/overview">
    Back to overview
  </Card>
</CardGroup>
